package gov.pbc.nn.kjgl.software.dao;

import gov.pbc.nn.core.dao.AbstractHibernateDao;
import gov.pbc.nn.core.dao.PbcnnCoreHibernateDao;
import gov.pbc.nn.kjgl.entity.ProjectChange;
import gov.pbc.nn.kjgl.entity.ProjectFile;
import gov.pbc.nn.uflo.UfloUtils;
import gov.pbc.nn.uflo.entity.Opinion;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;

import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.bdf2.core.orm.hibernate.ISessionCallback;
import com.bstek.uflo.client.service.ProcessClient;
import com.bstek.uflo.client.service.TaskClient;
import com.bstek.uflo.model.ProcessInstance;
import com.bstek.uflo.model.task.Task;
import com.bstek.uflo.service.TaskOpinion;

@Repository
public class YwDeptChangeDao extends AbstractHibernateDao {

	@Autowired
	@Qualifier(TaskClient.BEAN_ID)
	private TaskClient taskClient;

	@Resource(name = PbcnnCoreHibernateDao.BEAN_ID)
	private PbcnnCoreHibernateDao CoreHibernateDao;

	@Autowired
	@Qualifier(ProcessClient.BEAN_ID)
	private ProcessClient processClient;

	/**
	 * 获取流程变量state
	 * 
	 * @param processInstanceId
	 * @return
	 */

	public int getState(String processInstanceId) {
		if (processInstanceId != "") {
			ProcessInstance process = processClient.getProcessInstanceById(Long.valueOf(processInstanceId));
			String processVariable = processClient.getProcessVariable("state", process).toString();

			if (processVariable.equals("2")) {
				// 2表示变更申请提交到业务干系科长审核
				return 2;
			} else if (processVariable.equals("3")) {
				// 3表示业务干系科长审核同意，流程流转到 业务干系部门领导审核
				return 3;
			} else if (processVariable.equals("5")) {
				// 5表示业务干系部门领导审核同意后，流程流转到项目管理员审核的状态
				return 5;
			} else if (processVariable.equals("6")) {
				// 6表示业务干系部门领导审核不同意，流程流转到业务干系科长审核的状态
				return 6;
			} else if (processVariable.equals("7")) {
				// 7表示项目管理员审核同意后，给开发人员的状态
				return 7;
			} else if (processVariable.equals("8")) {
				// 8表示管理员不同意返回给业务干系部门领导
				return 8;
			} else if (processVariable.equals("22")) {
				// 22表示科技处不同意驳回给项目管理员
				return 22;
			}
		}
		return 0;
	}

	/**
	 * 获取业务干系科长审批时的相关数据
	 * 
	 * @param id
	 * @return
	 */
	public Map<String, Object> loadProjectByChange(String id) {
		final String sql = "select a.ID_ as pid,a.NAME_,a.DEPT_NAME_,b.ID_ as pcid,b.CHANGE_NAME_,b.CHANGE_DESCRIBE_,b.STATE_ from t_project as a inner join t_project_change as b on a.ID_ = b.PROJECT_ID_ where b.ID_= '"
				+ id + "' and b.INVALID_=0";
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("id", id);

		List<Object[]> ls = this.doInHibernateSession(new ISessionCallback<List<Object[]>>() {

			@Override
			public List<Object[]> doInSession(Session session) {
				return session.createSQLQuery(sql).list();
			}

		});
		Map<String, Object> map = new HashMap<String, Object>();
		if (!ls.isEmpty()) {
			for (Object[] o : ls) {
				map.put("projectId", o[0]);
				map.put("projectName", o[1]);
				map.put("projectDept", o[2]);
				map.put("changeId", o[3]);
				map.put("changeName", o[4]);
				map.put("changeDescribe", o[5]);
				map.put("state", o[6]);
				return map;
			}
		}
		return null;
	}

	/**
	 * 业务干系科长是否同意变更
	 * 
	 * @param taskId
	 * @param changeId
	 * @param opinionText
	 * @param i
	 *            i=1表示同意，i=0表示不同意
	 * @param type
	 *            type表示当前的处理状态。 1表示 业务干系科长审核。 2表示 业务干系部门领导审核。 3表示 项目管理员审核。
	 *            4表示科技处审核不通过返还给项目管理员审核
	 */
	public void agreeYwgxkz(String taskId, String changeId, String opinionText, int i, int type) {
		Map<String, Object> param = new HashMap<String, Object>();
		ProjectChange pc = this.getProjectChangeById(changeId);
		TaskOpinion option = new TaskOpinion(opinionText);
		Task task = taskClient.getTask(Long.valueOf(taskId));
		taskClient.start(Long.valueOf(taskId));
		final Opinion o = new Opinion();
		o.setBusKey(task.getBusinessId());
		o.setTaskId(Long.parseLong(taskId));
		o.setTaskName(task.getTaskName());
		o.setProcessName("业务部门提出的软件项目变更");
		o.setBusTable("T_PROJECT_CHANGE");
		o.setOpinion(opinionText);
		o.setUsername(ContextHolder.getLoginUser().getUsername());
		o.setDeptId(ContextHolder.getLoginUser().getDepts().get(0).getId());
		o.setDeptName(ContextHolder.getLoginUser().getDepts().get(0).getName());
		o.setCname(ContextHolder.getLoginUser().getCname());
		o.setNodeName(task.getNodeName());

		if (i == 1) {
			param.put("agree", 1);// 设置流程变量agree为1表示同意，流程往下流转
			switch (type) {
			case 1: {
				// pc.setState(11);// ProjectChange的State设置为11 表示 业务干系科长同意变更
				//
				// this.update(pc);
				param.put("state", "3");// 设置流程变量state为3表示业务干系科长审核同意后，给业务干系部门领导审核的状态
				break;
			}
			case 2: {
				// pc.setState(13);// ProjectChange的State设置为13 表示 业务干系部门领导同意变更
				// this.update(pc);
				param.put("state", "5");// 设置流程变量state为5表示业务干系部门领导审核同意后，给项目管理员的状态
				break;
			}
			case 3:
			case 4: {
				// pc.setState(15);// ProjectChange的State设置为15表示 项目管理员同意变更
				// this.update(pc);
				param.put("state", "7");// 设置流程变量state为7表示项目管理员审核同意后，给开发人员的状态
				break;
			}
			}

		} else if (i == 0) {
			param.put("agree", 0);// 设置流程变量agree为0表示不同意，流程驳回到上个节点
			switch (type) {
			case 1: {
				// pc.setState(12);// ProjectChange的State设置为12 表示 业务干系科长不同意变更
				// this.update(pc);
				param.put("state", "4");// 设置流程变量state为4表示业务干系科长驳回变更，返还给申请人
				break;
			}
			case 2: {
				// pc.setState(14);// ProjectChange的State设置为14 表示 业务干系部门领导不同意变更
				// this.update(pc);
				param.put("state", "6");// 设置流程变量state为6表示业务干系部门领导驳回变更，返还给业务干系科长审核
				break;
			}
			case 3:
			case 4: {
				// pc.setState(16);// ProjectChange的State设置为16 表示 项目管理员不同意变更
				// this.update(pc);
				param.put("state", "8");// 设置流程变量state为8表示项目管理员驳回变更，返还给业务干系部门领导
				break;
			}
			}

		}
		this.CoreHibernateDao.save(o);
		taskClient.complete(Long.valueOf(taskId), param, option);
	}

	/**
	 * 根据ProjectChange的id获取对应的ProjectChange
	 * 
	 * @param id
	 * @return
	 */
	public ProjectChange getProjectChangeById(String id) {
		DetachedCriteria query = DetachedCriteria.forClass(ProjectChange.class);
		query.add(Restrictions.or(Restrictions.eq("invalid", false), Restrictions.isNull("invalid")));
		query.add(Restrictions.eq("id", id));
		List<ProjectChange> ls = (List<ProjectChange>) this.query(query);
		if (!ls.isEmpty()) {
			return ls.get(0);
		}
		return null;
	}

	/**
	 * 根据ProjectChangeId获取相应的附件
	 * 
	 * @param id
	 * @return
	 */
	public List<ProjectFile> getProjectFileByChangeId(String id) {
		DetachedCriteria query = DetachedCriteria.forClass(ProjectFile.class);
		query.add(Restrictions.or(Restrictions.eq("invalid", false), Restrictions.isNull("invalid")));
		query.add(Restrictions.eq("ownerId", id));
		query.add(Restrictions.eq("type", 4));
		List<ProjectFile> ls = (List<ProjectFile>) this.query(query);
		if (!ls.isEmpty()) {
			return ls;
		}
		return null;
	}

	/**
	 * 提交项目组成员意见
	 * 
	 * @param taskId
	 * @param opinionText
	 */
	public void saveShOpinion(String taskId, String opinionText) {

		TaskOpinion option = new TaskOpinion(opinionText);
		Task task = taskClient.getTask(Long.valueOf(taskId));
		taskClient.start(Long.valueOf(taskId));
		final Opinion o = new Opinion();
		o.setProcessInstanceId(task.getProcessInstanceId());
		o.setBusKey(task.getBusinessId());
		o.setTaskId(Long.parseLong(taskId));
		o.setTaskName(task.getTaskName());
		o.setProcessName("业务部门提出的软件项目变更");
		o.setBusTable("T_PROJECT_CHANGE");
		o.setOpinion(opinionText);
		o.setUsername(ContextHolder.getLoginUser().getUsername());
		o.setDeptId(ContextHolder.getLoginUser().getDepts().get(0).getId());
		o.setDeptName(ContextHolder.getLoginUser().getDepts().get(0).getName());
		o.setCname(ContextHolder.getLoginUser().getCname());
		o.setNodeName(task.getNodeName());
		// CoreHibernateDao
		this.CoreHibernateDao.save(o);
		taskClient.complete(Long.valueOf(taskId), option);
	}

	/**
	 * 根据businessId获取项目组中除了管理员以外的其他成员Username
	 * 
	 * @param businessId
	 * @return
	 */
	public List<String> loadXmzUserByBusId(String businessId) {
		String hql = "select a.username from ProjectMember as a, ProjectChange as b where a.projectId=b.projectId and b.id=:id and a.projectRole !=0 and a.invalid=false";
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("id", businessId);
		List<String> users = this.query(hql, map);
		if (!users.isEmpty()) {
			return users;
		}
		return null;
	}

	/**
	 * 获取项目组成员意见
	 * 
	 * @param taskId
	 * @return
	 */
	public List<Map<String, Object>> loadXmzOpinion(String taskId) {
		Task task = taskClient.getTask(Long.valueOf(taskId));
		long processInstanceId = task.getProcessInstanceId();
		String businessId = task.getBusinessId();
		String taskName = task.getTaskName();

		// 根据businessId获取所有项目组成员
		String hql = "select a.username from ProjectMember as a, ProjectChange as b where a.projectId=b.projectId and b.id=:id and a.invalid=false";
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("id", businessId);
		List<String> users = this.query(hql, map);
		List<Map<String, Object>> value = new ArrayList<Map<String, Object>>();
		if (!users.isEmpty()) {
			List<Opinion> listOpinion = UfloUtils.getOpinions(processInstanceId, businessId, null, null, users);
			for (Opinion o : listOpinion) {
				Map<String, Object> opin = new HashMap<String, Object>();
				opin.put("userName", o.getUsername());
				opin.put("userCname", o.getCname());
				opin.put("opinion", o.getOpinion());
				value.add(opin);
			}
			return value;
		}
		return null;
	}

	/**
	 * 项目组管理员与科技处处长审核是否通过
	 * 
	 * @param taskId
	 * @param opinionText
	 * @param i
	 * @param type
	 */
	public void GlyAndKjcSh(String taskId, String opinionText, int i) {
		TaskOpinion option = new TaskOpinion(opinionText);
		Task task = taskClient.getTask(Long.valueOf(taskId));
		taskClient.start(Long.valueOf(taskId));
		final Opinion o = new Opinion();
		o.setProcessInstanceId(task.getProcessInstanceId());
		o.setBusKey(task.getBusinessId());
		o.setTaskId(Long.parseLong(taskId));
		o.setTaskName(task.getTaskName());
		o.setProcessName("业务部门提出的软件项目变更");
		o.setBusTable("T_PROJECT_CHANGE");
		o.setOpinion(opinionText);
		o.setUsername(ContextHolder.getLoginUser().getUsername());
		o.setDeptId(ContextHolder.getLoginUser().getDepts().get(0).getId());
		o.setDeptName(ContextHolder.getLoginUser().getDepts().get(0).getName());
		o.setCname(ContextHolder.getLoginUser().getCname());
		o.setNodeName(task.getNodeName());

		Map<String, Object> map = new HashMap<String, Object>();
		ProjectChange pc = this.getProjectChangeById(task.getBusinessId());
		if (task.getTaskName().equals("科技处处长审核评估意见")) {
			if (i == 1) {
				pc.setState(10);
				this.update(pc);
				map.put("agree", 1);
			} else if (i == 0) {
				map.put("agree", 0);
				map.put("state", "22");
			}
		} else {
			if (i == 1) {
				map.put("agree", 1);
			} else if (i == 0) {
				map.put("agree", 0);
			}
		}
		this.CoreHibernateDao.save(o);

		taskClient.complete(Long.valueOf(taskId), map, option);
	}
}
